package com.yq.ylmall.order.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yq.ylmall.client.cart.CartFeignClient;
import com.yq.ylmall.client.payment.PaymentFeignClient;
import com.yq.ylmall.client.product.ProductFeignClient;
import com.yq.ylmall.common.utils.AuthContextUtil;
import com.yq.ylmall.dto.cart.CartOrderDto;
import com.yq.ylmall.dto.order.OrderInfoDto;
import com.yq.ylmall.dto.order.OrderStatisticsDto;
import com.yq.ylmall.dto.order.PaymentInfoDto;
import com.yq.ylmall.dto.product.ProductDecreaseDto;
import com.yq.ylmall.model.acl.User;
import com.yq.ylmall.model.order.OrderInfo;
import com.yq.ylmall.model.order.OrderItem;
import com.yq.ylmall.model.order.OrderStatistics;
import com.yq.ylmall.order.mapper.OrderInfoMapper;
import com.yq.ylmall.order.mapper.OrderStatisticsMapper;
import com.yq.ylmall.order.service.IOrderInfoService;
import com.yq.ylmall.order.service.IOrderItemService;
import com.yq.ylmall.result.Result;
import com.yq.ylmall.result.ResultCode;
import com.yq.ylmall.utils.OrderCodeUtil;
import com.yq.ylmall.vo.order.OrderStatisticsVo;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.TransactionManagerHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author cherry
 * @since 2024-06-05
 */
@Service
@Slf4j
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements IOrderInfoService {

    @Autowired
    private OrderStatisticsMapper orderStatisticsMapper;

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private IOrderItemService orderItemService;

    @Resource
    private ProductFeignClient productFeignClient;

    @Resource
    private CartFeignClient cartFeignClient;

    @Resource
    private PaymentFeignClient paymentFeignClient;

    @Override
    public OrderStatisticsVo getOrderStatisticsData(OrderStatisticsDto orderStatisticsDto) {

        // 查询统计结果数据
        List<OrderStatistics> orderStatisticsList = orderStatisticsMapper.selectOrderList(orderStatisticsDto) ;

        //日期列表
        List<String> dateList = orderStatisticsList.stream().map(orderStatistics -> DateUtil.format(orderStatistics.getOrderDate(), "yyyy-MM-dd")).collect(Collectors.toList());

        //统计金额列表
        List<BigDecimal> amountList = orderStatisticsList.stream().map(OrderStatistics::getTotalAmount).collect(Collectors.toList());

        // 创建OrderStatisticsVo对象封装响应结果数据
        OrderStatisticsVo orderStatisticsVo = new OrderStatisticsVo() ;
        orderStatisticsVo.setDateList(dateList);
        orderStatisticsVo.setAmountList(amountList);

        // 返回数据
        return orderStatisticsVo;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public Result createOrder(OrderInfoDto orderInfoDto) {
        try {
            log.warn("订单信息: {}", orderInfoDto);
            OrderInfo orderInfo = new OrderInfo();
            BeanUtils.copyProperties(orderInfoDto, orderInfo);
            orderInfo.setOrderStatus(0);
            orderInfo.setOrderNo(OrderCodeUtil.generateUniqueKey());
            Result result = null;
            if (super.save(orderInfo)) {
                orderInfoDto.setOrderNo(orderInfo.getOrderNo());
                orderInfoDto.setUserId(orderInfo.getUserId());
                List<String> skuIds = orderInfoDto.getOrderItemList().stream().map(orderItem -> orderItem.getSkuId()).collect(Collectors.toList());
                orderInfoDto.getOrderItemList().forEach(orderItem -> {
                    orderItem.setOrderId(orderInfo.getId());
                    OrderItem item = new OrderItem();
                    BeanUtils.copyProperties(orderItem, item);
                    orderItemService.save(item);
                    ProductDecreaseDto decreaseDto = new ProductDecreaseDto();
                    decreaseDto.setProductId(orderItem.getProductId());
                    decreaseDto.setSkuId(orderItem.getSkuId());
                    decreaseDto.setCount(orderItem.getSkuNum());
                    productFeignClient.decreaseStock(decreaseDto);
                });
                CartOrderDto cartOrderDto = new CartOrderDto();
                cartOrderDto.setUserId(orderInfoDto.getUserId());
                cartOrderDto.setSkuIds(skuIds);
                cartFeignClient.batchRemove(cartOrderDto);
                result = paymentFeignClient.nativePay(orderInfoDto);
                if (result.getCode() != 200) {
                    throw new RuntimeException(ResultCode.CREATE_ORDER_FAIL.getMessage());
                }
            }
            return result;
        } catch (Exception e) {
            try {
                e.printStackTrace();
                log.error("创建订单失败：{}", e.getMessage());
                TransactionManagerHolder.get().rollback(RootContext.getXID());
            } catch (TransactionException ex) {
                ex.printStackTrace();
            }
            throw new RuntimeException(ResultCode.CREATE_ORDER_FAIL.getMessage());
        }
    }

    @Override
    public void updatePaymentInfo(PaymentInfoDto paymentInfo) {
        baseMapper.update(null, Wrappers
                .<OrderInfo>lambdaUpdate()
                .eq(OrderInfo::getOrderNo, paymentInfo.getOrderNo())
                .set(OrderInfo::getOrderStatus, paymentInfo.getPaymentStatus()));
        orderInfoMapper.updatePaymentInfo(paymentInfo);
    }
}
